package flp.gui.view.random;

import flp.solvers.random.RandomSettings;
import flp.solvers.random.RandomSolver;
import flp.gui.ResultViewerForm;
import flp.Layout;
import flp.gui.ExceptionHandler;
import flp.problem.ProblemInstance;
import flp.solvers.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

/**
 * Klasa obslugujaca optymalizacje obliczen dla algorytmu
 * losowego. Jest to watek tworzacy formy,
 * uruchamiajacy monitor i solvera optymalizujacego.
 * 
 * @author Necro
 */
public class RandomSolverHandler implements Runnable
{
    /** Instancja badanego problemu. */
    ProblemInstance problem;
    
    /** Ustawienia algorytmu. */
    RandomSettings settings;
    
     /** Monitor nasluchujacy. */
    RandomOptimizationListener optimizationMonitor;
    
    /** Instancja solvera ktory przeprowadza optymalizacje. */
    RandomSolver currentSolver;
    
    /** Forma pokazujaca rezultaty pomiarow. */
    ResultViewerForm view;
    
    /** Panel zawierajacy dane liczbowe. */
    RandomInfoPanel dataPanel;
    
    /** Wykres obrazujacy postep. */
    RandomChart chart;
    
    /** Wynik optymalizacji. */
    Layout top;
    
    /** Flaga sygnalizujaca zakonczenie procesu optymalizacji. */
    boolean finished;
    
    /** Ilosc sekund ktore uplynely od rozpoczecia obliczen. */
    private int secondsElapsed;
    
    /** Timer obslugujacy zegar czasu obliczen. */
    private Timer timer;

    public RandomSolverHandler(ProblemInstance problem, RandomSettings settings)
    {
        this.problem = problem;
        this.settings = settings;
        this.finished = false;

        timer = new Timer(1000, new TimerLabelHandler());
        timer.setDelay(1000);

        dataPanel = new RandomInfoPanel(settings);

        chart = new RandomChart("FLP Algorytm Losowy");
        view = ResultViewerForm.create("FLP Algorytm Losowy", chart.getChartPanel(),
                dataPanel);
    }

    class TimerLabelHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            if (finished){
                timer.stop();
            }
            secondsElapsed++;
            dataPanel.setTimeLabelText(String.format("%02d:%02d", secondsElapsed / 60,
                    secondsElapsed % 60));
        }
    }

    public void run()
    {
        try
        {
            optimizationMonitor = new RandomOptimizationListener(this);
            currentSolver = new RandomSolver(problem, settings, optimizationMonitor);
            view.setParentSolver(currentSolver);
            
            timer.start();
            optimizationMonitor.start();
            Layout result = currentSolver.computeSolution();
            timer.stop();
            finished = true;
            
            if (result == null){
                ExceptionHandler.showWarningPane(view);
                view.dispose();
                
            } else {
                dataPanel.showResult(result);
                view.disableCancelButton();
            }
        }
        catch (Exception e)
        {
            ExceptionHandler.handle(view, e);
        }
    }
}
